package com.link.base.base.common.controller;

import com.alibaba.fastjson.JSONObject;
import com.link.base.user.model.CoreUser;
import com.link.base.base.common.model.Menu;
import com.link.base.base.common.model.MenuAndCorpModel;
import com.link.base.base.common.model.MenuTree;
import com.link.base.base.common.service.MenuService;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.annotations.JsonParam;
import com.link.core.basic.controller.BasicController;
import com.link.core.basic.controller.BasicControllerException;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.Filter;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.service.BasicService;
import com.link.core.basic.service.ServiceException;
import com.link.core.modules.export.ExportFactory;
import com.link.core.modules.export.ExportWriter;
import com.link.core.util.AppConstants;
import com.link.core.util.RedisUtil;
import com.link.core.util.UserUtil;
import com.link.core.util.redisclient.LinkRedisClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * 菜单配置模块
 *
 * @author unknwon
 * @version 1.0
 * @date: 2018/11/8 19:09
 */

@Controller
@RequestMapping("/link/menu")
public class MenuController extends BasicController<Menu> {
    @Resource
    private MenuService menuService;

    @Override
    public BasicService<Menu> getBasicService() throws Exception {
        return menuService;
    }

    /**
     * 没有匹配Idd
     *
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/noMatchId", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> noMatchId(HttpSession session, HttpServletRequest request,
                                         HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        List<Menu> list = null;
        try {
            list = new ArrayList<Menu>();
            result.put("success", true);
            result.put("rows", list);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 清除缓存
     *
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/flushCache")
    @ResponseBody
    public Map<String, Object> flushCache(HttpSession session, HttpServletRequest request,
                                          HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        LinkRedisClient jedis = RedisUtil.getJedis();
        try {
            CoreUser user = UserUtil.getUser();
            String flushKeysPattern = null;
            if (AppConstants.ADMIN_CORP_ID.equals(user.getCorpid())) {
                //清除所有账套的缓存
                flushKeysPattern = AppConstants.USER_MENU_SET + ":*";
            } else {
                //清除当前账套的
                flushKeysPattern = AppConstants.USER_MENU_SET + ":" + user.getCorpid() + ":*";
            }
            Set<String> set = jedis.keys(flushKeysPattern);
            if (set.size() > 0) {
                String[] keyStrs = new String[set.size()];
                int i = 0;
                Iterator<String> it = set.iterator();
                while (it.hasNext()) {
                    String keyStr = it.next();
                    keyStrs[i] = keyStr;
                    i++;
                }
                jedis.del(keyStrs);
            }
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        } finally {
            RedisUtil.returnResource(jedis);
        }
        return result;
    }

    @RequestMapping(value = "/manageInit/{type}", method = RequestMethod.POST)
    public void manageInit(@PathVariable String type, HttpSession session, HttpServletRequest request,
                           HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        List<Menu> list = null;
        String resultJson = null;
        LinkRedisClient jedis = null;
        try {
            CoreUser user = UserUtil.getUser();
            list = menuService.getMenuListByMenuTyepSelect(type, user.getId(), session);
            result.put("success", true);
            result.put("rows", list);
            resultJson = JSONObject.toJSONString(result);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
            resultJson = JSONObject.toJSONString(result);
        } finally {
            RedisUtil.returnResource(jedis);
        }
        responseJson(request, response, resultJson);
    }

    /**
     * 获取当前登录用户一级菜单接口
     *
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/getUserFstMenu")
    @ResponseBody
    public Map<String, Object> queryFstMenuList(HttpSession session, HttpServletRequest request,
                                                HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        List<Menu> list = null;
        try {
            CoreUser user = UserUtil.getUser();
            list = menuService.queryFstMenuList(user);
            result.put("success", true);
            result.put("rows", list);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 站点地图接口，获取当前用所有可访问菜单
     * @author 姚润发
     * @date 2019/12/13 12:02
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "siteMap")
    @ResponseBody
    public Map<String, Object> siteMap(HttpSession session, HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        CoreUser user = null;
        List<Menu> list = null;
        try {
            user = UserUtil.getUser();
            list = menuService.getMenuListByMenuTyepSelect("", user.getId(), session);
            result.put("success", true);
            result.put("rows", list);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询一级菜单
     *
     * @param qps
     * @param menu
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/queryFstLevel")
    @ResponseBody
    public Map<String, Object> queryFstLevel(@JsonParam QueryParams qps, Menu menu, HttpSession session, HttpServletRequest request,
                                             HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            qps.addFilter(new Filter("menuGrade", "0"));
            Menu t = (Menu) BasicModel.transformClass(menu, qps);
            List<Menu> list = getBasicService().queryByExamplePage(t);
            result.put("success", true);
            result.put("rows", list);
            this.pushCurrentDataCache(list, session.getId(), "base", false);
            result.put("total", getCount(t, list.size()));
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Menu>());
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 一级菜单导出
     */
    @Override
    @RequestMapping(value = "/queryFstLevel/exportData")
    @ResponseBody
    public Map<String, Object> exportData(@JsonParam Menu entity,@JsonParam QueryParams qps, HttpSession session, HttpServletRequest request,
                                          HttpServletResponse response) {
        LCLogger.info().withMessageKey("queryFstLevel/exportData").withMessage("导出列表...").flush();
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            qps.preDealSecurity(request);
            qps.addFilter(new Filter("menuGrade", "0"));
            ExportWriter exportWriter;
            String exportType = "xlsx";
            String exportFileType = qps.getExportFileType();
            if (exportType.equals(exportFileType)) {
                exportWriter = ExportFactory.newExcelInstance(qps);
            } else {
                exportWriter = ExportFactory.newInstance(qps);
            }
            Menu t = (Menu) BasicModel.transformClass(entity.getClass(), qps);
            List<Menu> list = getBasicService().queryByExamplePage(t);
            while (!qps.getStopExport()) {
                exportWriter.wirteData(list);
            }
            result.put("success", true);
            result.put("url", exportWriter.getUrlPath());
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询二级菜单
     *
     * @param qps
     * @param menu
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/items")
    @ResponseBody
    public Map<String, Object> items(@JsonParam QueryParams qps,@JsonParam Menu menu, HttpSession session, HttpServletRequest request,
                                     HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        List<Menu> list = new ArrayList<Menu>();
        try {
            qps.preDealSecurity(request);
            qps.invokePreFilterAndSorter();
            List<Filter> filterList = qps.getFilterByProperty("menuType");
            if (filterList == null || filterList.size() == 0) {
                qps.addFilter(new Filter("menuType", "noMatchId"));
            }


            Menu t = (Menu) BasicModel.transformClass(menu, qps);
            beforQueryAllOrExample(t, request);
            beforQueryExample(t, request);
            list = getBasicService().queryByExamplePage(t);
            result.put("success", true);
            result.put("rows", list);
            this.pushCurrentDataCache(list, session.getId(), "base", false);
            result.put("total", getCount(t, list.size()));
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", list);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询安全性菜单列表
     * @author 姚润发
     * @date 2016/
     * @param qps
     * @param menu
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/subItemList")
    @ResponseBody
    public Map<String, Object> subItemList(@JsonParam QueryParams qps,@JsonParam Menu menu, HttpSession session, HttpServletRequest request,
                                           HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        List<Menu> list = new ArrayList<Menu>();
        try {
            qps.invokePreFilterAndSorter();
            List<Filter> filterList = qps.getFilterByProperty("parentMenuId");
            if (filterList == null || filterList.size() == 0) {
                qps.addFilter(new Filter("parentMenuId", "noMatchId"));
            }
            Menu t = (Menu) BasicModel.transformClass(menu, qps);
            beforQueryAllOrExample(t, request);
            beforQueryExample(t, request);
            list = getBasicService().queryByExamplePage(t);
            result.put("success", true);
            result.put("rows", list);
            this.pushCurrentDataCache(list, session.getId(), "base", false);
            result.put("total", getCount(t, list.size()));
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", list);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 看样子是添加菜单数据前校验，但前端没找到相应调用，待确认
     * @author unkonw
     * @date 2019/12/13 12:05
     * @param record
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/addBefore", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> addBefore(@JsonParam Menu record, HttpSession session, HttpServletRequest request,
                                         HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            if (StringUtils.isEmpty(record.getMenuType())) {
                throw new BasicControllerException("传入菜单编码数据异常");
            }
            Menu menu = menuService.queryByMenuType(record);
            if (menu != null) {
                result.put("success", false);
                result.put("result", "该菜单类型：" + record.getMenuType() + "已经存在！");
            } else {
                result.put("success", true);
            }
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询当前用户所有可访问菜单，用于生成菜单一览报表
     * @author unknown
     * @date 2019/12/13 12:06
     * @param user
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/queryMenuListByUser", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> queryMenuByUser(Long user, HttpSession session, HttpServletRequest request,
                                               HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);

        try {
            CoreUser coreUser = new CoreUser();
            coreUser.setId(user);
            result = menuService.queryAllMenuByUser(coreUser, session);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询当前用户所有菜单，用于生成页面菜单导航栏
     * @author 姚润发
     * @date 2019/12/13 12:09
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/queryCurrentMenuList", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> queryMenuByCurrentUser(HttpSession session, HttpServletRequest request,
                                                      HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        CoreUser user = UserUtil.getUser();
        try {
            if (user == null) {
                result.put("success", false);
                result.put("result", "获取用户失败，用户未登录或已过期");
                return result;
            }
            result = menuService.queryAllMenuByUser(user, session);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询当前登录用户职责内的所有DMS菜单
     */
    @RequestMapping(value = "/queryOwnDmsMenu")
    @ResponseBody
    public Map<String, Object> queryOwnDmsMenu(HttpSession session,
                                               HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            CoreUser user = UserUtil.getUser();
            Long userId = user.getId();
            List<Menu> list = menuService.queryDmsFstMenuList(userId);
            result.put("success", true);
            result.put("rows", list);
        } catch (ServiceException e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Menu>());
            result.put("result", e.getMessage());
            result.put("detailMessage", e.getMessage());
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Menu>());
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 深度复制安全性菜单
     *
     * @param record
     * @return
     */
    @RequestMapping(value = "/deepCopySecurityMenu", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> deepCopySecurityMenu(@JsonParam Menu record) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            if (null == record.getId()) {
                throw new ServiceException("PUBLIC-007");
            }
            Menu menu = menuService.deepCopySecurityMenu(record);
            result.put("success", true);
            result.put("newRow", menu);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 所有菜单必须配置安全性菜单--修数据
     *
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/fixData", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> fixData(HttpSession session, HttpServletRequest request,
                                       HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);

        try {
            CoreUser user = UserUtil.getUser();
            if (user != null && AppConstants.ADMIN_CORP_ID.equals(user.getCorpid())) {
                menuService.fixData();
            }

            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    @Override
    public void beforUpsert(Menu menu, HttpServletRequest request) {
        menu.setLoginCorpId(null);
        menu.setCorpid(null);
    }

    @Override
    public void beforDelete(Menu menu, HttpServletRequest request) {
        menu.setLoginCorpId(null);
    }


    @RequestMapping(value = "/distributeMenuByAssign", method = RequestMethod.POST)
    public Map<String, Object> distributeMenusByAssign(@RequestBody MenuAndCorpModel menuAndCorpModel) {

        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            if (Objects.isNull(menuAndCorpModel)) {
                throw new ServiceException("PUBLIC-015");
            }
            if (StringUtils.isBlank(menuAndCorpModel.getAssignCorpCode()) || CollectionUtils.isEmpty(menuAndCorpModel.getMenuModels())) {
                throw new ServiceException("PUBLIC-015");
            }
            menuService.distributeMenuByAssign(menuAndCorpModel);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }


    /**
     * 查询当前职责内的所有DMS一级菜单以及二级菜单
     */
    @RequestMapping(value = "/queryAllDmsMenuAndSubMenu")
    @ResponseBody
    public Map<String, Object> queryAllDmsMenuAndSubMenu(@JsonParam Menu entity, HttpSession session,
                                                         HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            List<Menu> menuList = menuService.queryAllDmsMenuAndSubMenu(entity);
            result.put("success", true);
            result.put("rows", menuList);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Menu>());
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询当前职责内的所有一/二级菜单以及安全性菜单
     */
    @RequestMapping(value = "/querySafetyMenuList")
    @ResponseBody
    public Map<String, Object> querySafetyMenuList(@JsonParam Menu entity, HttpSession session,
                                                         HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            List<MenuTree> menuList = menuService.querySafetyMenuList(entity);
            result.put("success", true);
            result.put("rows", menuList);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Menu>());
            result.put("result", e.getMessage());
        }
        return result;
    }
}
